package common.security.authentication.listener;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.configuration.Configuration;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.Authentication;

import common.hibernate.service.BaseService;
import common.log.service.LogService;
import common.log.util.LogModule;
import common.log.util.LogType;
import common.log.vo.ApplicationLog;
import common.rbac.po.User;
import common.security.event.LogoutEvent;

public class SecurityApplicationListener implements ApplicationListener<ApplicationEvent> {
	
	private  Map<String, Integer> lockUserMap = new HashMap<String, Integer>();
	
	private BaseService baseService;
	
	private Configuration config;
	
	private LogService logService;
	

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if(event instanceof AuthenticationSuccessEvent) {
			AuthenticationSuccessEvent authEvent = (AuthenticationSuccessEvent) event;
	        Authentication authentication = (Authentication) authEvent.getSource();
	        String userName = authentication.getName();
	        cleanCount(userName);
	        
	        User user = baseService.findOne("from User where name = ? ", userName);
	        user.setFlushDt(new Date());
	        baseService.update(user);
			logService.saveLog(new ApplicationLog(event, LogModule.LOGIN, LogType.ADD, true, "登录成功"));
		} else if(event instanceof AbstractAuthenticationFailureEvent) {
			AbstractAuthenticationFailureEvent authEvent = (AbstractAuthenticationFailureEvent) event;
	        Authentication authentication = (Authentication) authEvent.getSource();
	        String userId = authentication.getName();
	        addCount(userId);
	        logService.saveLog(new ApplicationLog(event, LogModule.LOGIN, LogType.ADD, false, "登录失败"));
		} else if(event instanceof LogoutEvent){
			logService.saveLog(new ApplicationLog(event, LogModule.LOGIN, LogType.ADD, true, "退出成功"));
			// LogoutEvent authEvent = (LogoutEvent) event;
	        // Authentication authentication = (Authentication) authEvent.getSource();
	        // String userId = authentication.getName();
			// CommonAction.warns.remove(userId);
		}
	}
	
	protected void cleanCount(String userId) {
		lockUserMap.remove(userId);
	}

	protected void addCount(String userName) {
	    Map<String, Integer> lockUserMap = getLockUserMap();
	    Integer count = lockUserMap.get(userName);
	    if (count == null) {
	        lockUserMap.put(userName, Integer.valueOf(1));
	    } else {
	        int resultCount = count.intValue() + 1;
	        if (resultCount >= config.getInt("lockUserOnAuthenticationFailureBadCredentials", 3)) {
	            User userInfo = (User) baseService.findOne("from User where name = ? ", userName);
	            if (null != userInfo) {
					userInfo.setNonLock(false);
					baseService.update(userInfo);
				}
	        } else {
	            lockUserMap.put(userName, Integer.valueOf(resultCount));
	        }
	    }
	}

	public Map<String, Integer> getLockUserMap() {
		return lockUserMap;
	}

	public void setLockUserMap(Map<String, Integer> lockUserMap) {
		this.lockUserMap = lockUserMap;
	}

	public void setBaseService(BaseService baseService) {
		this.baseService = baseService;
	}

	public void setConfig(Configuration config) {
		this.config = config;
	}

	public void setLogService(LogService logService) {
		this.logService = logService;
	}



}
